package java_thinking.unit_21._21_5;

import net.jcip.annotations.GuardedBy;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

/**
 * @Desc:   5-16 使用HashMap 和同步机制来初始化缓存 可伸缩性问题的反面案例，不要这么做
 *              1.如果多个线程在排队等待还未计算出结果，那么 compute 方法的计算时间可能比
 *                没有“缓存”操作计算时间更长
 * @author: cww
 * @DateTime: 2019/6/10 8:59
 */

public class Memoizer1<A, V> {
    @GuardedBy("this") private final Map<A, V> cache = new HashMap<>();
    private final Computable<A, V> c;

    public Memoizer1(Computable<A, V> c) {
        this.c = c;
    }

    /**
     * 使用了保守的对整个 compute 方法进行同步。但会带来一个明显的可伸缩性问题
     * @param arg
     * @return
     * @throws InterruptedException
     */
    public synchronized V compute(A arg) throws InterruptedException {
        V result = cache.get(arg);
        if (result == null) {
            result = c.compute(arg);
            cache.put(arg, result);
        }
        return result;
    }
}

interface Computable<A, V> {
    V compute(A arg) throws InterruptedException;
}

class ExpensiveFunction implements Computable<String, BigInteger> {

    // 模拟经过长时间计算后
    @Override
    public BigInteger compute(String arg) throws InterruptedException {
        return new BigInteger(arg);
    }
}

